package com.agree.util.excel.handlers.poi;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.agree.util.excel.config.Configuration;
import com.agree.util.excel.entity.InterfaceColMapEntity;
import com.agree.util.excel.entity.TableInfo;
import com.agree.util.excel.enums.MappingConfig;
import com.agree.util.excel.annotations.Items;
import com.agree.util.excel.handlers.mapping.MappingHandler;
import com.agree.util.excel.enums.MappingType;
import com.google.common.collect.Maps;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by wangmu on 2017/12/5.
 */
public class DefaultPOIHandler {

    private Configuration configuration;

    public DefaultPOIHandler() {
    }

    public DefaultPOIHandler(Configuration configuration) {
        this.configuration = configuration;
    }

    public Workbook createSheetExcel(ExcelType excelType, Class<InterfaceColMapEntity> entityClass, TableInfo tableInfo) {

        MappingType[] mappingTypes = getMappingTypes(entityClass,tableInfo.getName());
        if(mappingTypes.length == 1) {
            return createOneSheetExcel(excelType,entityClass,tableInfo,mappingTypes[0]);
        }
        List<Map<String, Object>> sheetList = Arrays.stream(mappingTypes)
                .filter(m -> MappingConfig.valueOfNoException(tableInfo.getName() + "_" + m.getName()) != null)
                .map(m -> {
                    List<InterfaceColMapEntity> data = getData(entityClass, tableInfo, m);
                    Map<String, Object> sheet = Maps.newHashMap();
                    ExportParams params = new ExportParams(tableInfo.getComment(),m.getValue(),excelType) ;
                    //params.setStyle(ExcelExportStyler.class);
                    sheet.put("title", params);
                    sheet.put("entity", entityClass);
                    sheet.put("data", data);
                    return sheet;
                }).collect(Collectors.toList());
        return ExcelExportUtil.exportExcel(sheetList,excelType);
    }

    private Workbook createOneSheetExcel(ExcelType excelType, Class<InterfaceColMapEntity> entityClass, TableInfo tableInfo,MappingType handlerConfig) {
        List<InterfaceColMapEntity> data = getData(entityClass, tableInfo, handlerConfig);
        if(data != null) {
            return ExcelExportUtil.exportExcel(new ExportParams(tableInfo.getComment(),handlerConfig.getValue(),excelType),entityClass,data);
        }
        throw new RuntimeException("获取表格数据失败!");
    }

    public void writeExcel(Workbook workbook,File file){
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(file);
            workbook.write(outputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
                outputStream = null;
            }
        }
    }

    private List<InterfaceColMapEntity> getData(Class<InterfaceColMapEntity> entityClass,TableInfo tableInfo,MappingType handlerConfig) {
        Class<? extends MappingHandler> handlerClass = handlerConfig.getHandlerClass();
        List<InterfaceColMapEntity> list = null;
        try {
            MappingConfig tableConfig = MappingConfig.valueOfNoException(tableInfo.getName() + "_" + handlerConfig.getName());
            Constructor<? extends MappingHandler> constructor = handlerClass.getConstructor(MappingConfig.class);
            MappingHandler mappingHandler = constructor.newInstance(tableConfig);
            list = mappingHandler.mapProperties(tableInfo);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    private MappingType[] getMappingTypes( Class<InterfaceColMapEntity> entityClass,String tableName) {
        //获取执行类型
        Items items = entityClass.getAnnotation(Items.class);
        MappingType[] handlerConfigs = {};
        if(items == null && configuration == null) {
            return handlerConfigs = new MappingType[]{MappingType.SIMPLE_ADD
                    , MappingType.SIMPLE_DELETE, MappingType.SIMPLE_UPDATE
                    , MappingType.SIMPLE_QUERY};
        } else if(items == null && configuration != null) {
            handlerConfigs = configuration.mppingConfig().tableMappings().getMappingTypeByTableName(tableName);
        } else if(items != null && configuration == null){
            handlerConfigs = items.invokeHandlers();
        }
        return handlerConfigs;
    }

}
